package com.tvunetworks.center.user.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tvunetworks.center.common.constant.LocalConstant;
import com.tvunetworks.center.common.model.param.PeerIdParam;
import com.tvunetworks.center.gs.model.Device;
import com.tvunetworks.center.user.mapper.UserDeviceMapper;
import com.tvunetworks.center.user.model.CustomizedUserGroup;
import com.tvunetworks.center.user.model.param.PageCustomizedChannelParam;
import com.tvunetworks.center.user.model.vo.CustomizedChannelVo;
import com.tvunetworks.center.user.model.vo.PeerIdGroupVo;
import com.tvunetworks.center.user.model.vo.customized.TCanLiveRVo;
import com.tvunetworks.center.user.service.*;
import com.tvunetworks.center.user.service.feign.CustomizedDeviceFeignService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program: tvucc-aggregator
 * @description: CustomizedChannelServiceImpl
 * @author lebronchen
 * @create: 2020-03-17 13:18
 **/
@Service
@Slf4j
public class CustomizedChannelServiceImpl implements CustomizedChannelService {

    @Autowired
    private UserDeviceMapper userDeviceMapper;
    @Autowired
    private CustomizedDeviceFeignService customizedDeviceFeignService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UserDeviceService userDeviceService;
    @Autowired
    private CustomizedUserDeviceGroupService customizedUserDeviceGroupService;
    @Autowired
    private CustomizedUserGroupService customizedUserGroupService;

    @Value("${customized.liveFilterGroup}")
    private boolean liveFilterGroup;
    @Value("${customized.liveFilterPair}")
    private boolean liveFilterPair;
    @Value("${showAutoROnManualChannel}")
    private boolean showAutoROnManualChannel;

    @Override
    public PageInfo<CustomizedChannelVo> pageChannel(PageCustomizedChannelParam param) {
        List<String> userPeerIds = userDeviceMapper.listUserDevice(param.getUserId(), param.getCondition(), "R");
        if (CollectionUtils.isEmpty(userPeerIds)) {
            return new PageInfo<>();
        }

        // 根据参数 manual 过滤 手动/自动 设备
        Integer manual = param.getManual();
        List<String> autoPeerIds = customizedDeviceFeignService.listAutoPeerIds();
        if (manual != null) {

            if (autoPeerIds == null) {
                autoPeerIds = new ArrayList<>();
            }
            if (manual.intValue() == 1) {
                // 过滤手动的设备
                userPeerIds.removeAll(autoPeerIds);
            } else {
                // 过滤自动的设备
                userPeerIds.retainAll(autoPeerIds);
            }
        }
        if (CollectionUtils.isEmpty(userPeerIds)) {
            return new PageInfo<>();
        }

        // 通过 memcache 过滤出用户在 online 的 R，DB 中的 status 可能不准确
        List<Device> devices = deviceService.listCurrentDevice(userPeerIds);
        Optional.ofNullable(devices);
        List<String> idlePeerIds = devices.stream().filter(item -> LocalConstant.DeviceStatus.ONLINE.equals(item.getStatus())).map(Device::getPeerId).collect(Collectors.toList());
        List<String> livingPeerIds = devices.stream().filter(item -> LocalConstant.DeviceStatus.LIVING.equals(item.getStatus())).map(Device::getPeerId).collect(Collectors.toList());
        // 根据参数 idle 过滤 idle/occupy 设备
        Integer idle = param.getIdle();
        if (idle != null) {
            if(idle.intValue() == 0){
                userPeerIds.removeAll(idlePeerIds);
            }else {
                userPeerIds.retainAll(idlePeerIds);
            }
        }

        if(CollectionUtils.isEmpty(userPeerIds)){
            return new PageInfo<>();
        }

        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        // 这里必须查询出 CustomizedChannelVo 类型，否则还要去封装 PageInfo
        List<CustomizedChannelVo> list = userDeviceMapper.listCustomizedChannelVo(userPeerIds);
        if (CollectionUtils.isEmpty(list)) {
            return new PageInfo<>();
        }

        //设置GroupName信息
        String defaultGroupName = null;
        CustomizedUserGroup defaultGroup = customizedUserGroupService.getUserDefaultGroup(param.getUserId());
        Map<String, PeerIdGroupVo> peerIdGroupMap = null;

        if(defaultGroup != null){
            peerIdGroupMap = customizedUserDeviceGroupService.mapPeerIdGroup(param.getUserId(), userPeerIds);
            defaultGroupName = defaultGroup.getGroup();
        }

        peerIdGroupMap = Optional.ofNullable(peerIdGroupMap).orElse(new HashMap<>(0));

        for (CustomizedChannelVo vo : list) {
            String peerId = vo.getPeerId();

            Device device = deviceService.getCurrentDevice(peerId);
            if (device != null) {
                BeanUtils.copyProperties(device, vo);
            }

            //根据是否是自动，设置manual值
            if(autoPeerIds.contains(peerId)){
                vo.setManual(0);
            }else {
                vo.setManual(1);
            }

            //根据是否被占用，设置occupyStatus
            if (idlePeerIds.contains(peerId)){
                vo.setOccupyStatus(1);
            } else if (livingPeerIds.contains(peerId)) {
                vo.setOccupyStatus(0);
            } else {
                vo.setOccupyStatus(2);
            }

            //设置groupname
            PeerIdGroupVo gv = peerIdGroupMap.get(peerId);
            if (gv != null) {
               // 设置 group
                vo.setGroup(gv.getGroup());
            } else {
                // 设置 默认 group
                vo.setGroup(defaultGroupName);
            }

            // TODO 设置 占用设备等信息

        }

        return new PageInfo<>(list);
    }

    @Override
    public TCanLiveRVo listR(String userId, PeerIdParam param) {
        String peerId = param.getPeerId();
        String condition = param.getCondition();


        TCanLiveRVo result = new TCanLiveRVo();

        Device source = deviceService.getCurrentDevice(peerId);
        if (source == null) {
            return result;
        }
        String sourceGroup = customizedUserDeviceGroupService.getUserDeviceGroupWithDefault(userId, peerId);

        // 用户所有 R
        List<String> userRids = userDeviceService.listUserCacheRids(userId);
        if (CollectionUtils.isEmpty(userRids)) {
            return result;
        }

        if (liveFilterGroup) {
            // 过滤掉和 Source 不是一个分组的 R
            customizedUserDeviceGroupService.filterDeviceByGroupName(userId, sourceGroup, userRids);
        }

        if (liveFilterPair) {
            userRids = userDeviceService.listSourceAvailableRids(userId, peerId, source.getType(), condition);
        }

        // 自动通道所有 R
        List<String> autoRids = customizedDeviceFeignService.listAutoPeerIds();
        if (autoRids == null) {
            autoRids = new ArrayList<>();
        }

        List<String> liveWithAutoRids = new ArrayList<>();
        List<String> liveWithManualRids = new ArrayList<>();
        List<String> otherAutoRids ;
        List<String> otherManualRids ;

        String livePeerId = source.getLivePeerId();
        if (!StringUtils.isEmpty(livePeerId)) {
            if (livePeerId.endsWith(";")) {
                // 如果是 ; 结尾的 去掉
                livePeerId = livePeerId.substring(0, livePeerId.length() -1);
            }
            // Source 所有的 livePeerId
            Set<String> livePeerIds = Stream.of(livePeerId.split(";")).collect(Collectors.toSet());
            livePeerIds.retainAll(userRids);
            if (!CollectionUtils.isEmpty(livePeerIds)) {
                liveWithAutoRids = new ArrayList<>(livePeerIds);
                // 和 Source 正在直播的，自动通道的 R
                liveWithAutoRids.retainAll(autoRids);
                // 和 Source 正在直播的，手动通道的 R
                livePeerIds.removeAll(liveWithAutoRids);
                liveWithManualRids = new ArrayList<>(livePeerIds);
            }

        }

        // 用户所有 R 移除掉已经算出来的 liveWithR
        //  userRids.removeAll(liveWithAutoRids);
        //  userRids.removeAll(liveWithManualRids);

        otherAutoRids = new ArrayList<>(userRids);
        // 不和 Source 正在直播的，自动通道的 R
        otherAutoRids.retainAll(autoRids);
        otherAutoRids.removeAll(liveWithAutoRids);
        // 不和 Source 正在直播的，手动通道的 R
        userRids.removeAll(autoRids);
        otherManualRids = userRids;
        otherManualRids.removeAll(liveWithManualRids);

        List<Device> liveWithAutos = filterAndSortDevice(liveWithAutoRids, condition);
        List<Device> liveWithManuals = filterAndSortDevice(liveWithManualRids, condition);
        List<Device> otherAutos = filterAndSortDevice(otherAutoRids, condition);
        List<Device> otherManuals = filterAndSortDevice(otherManualRids, condition);
        result.setLiveWithManuals(liveWithManuals)
                .setOtherManuals(otherManuals);
        if (showAutoROnManualChannel) {
            result.setLiveWithAutos(liveWithAutos)
                    .setOtherAutos(otherAutos);
        }
        return result;
    }

    private List<Device> filterAndSortDevice(List<String> peerIds, String condition) {
        List<Device> devices = deviceService.listCurrentDevice(peerIds, condition);
        if (devices == null) {
            return new ArrayList<>(0);
        }
        devices = devices.stream().sorted(Comparator.comparing(Device::getName))
                        .sorted(Comparator.comparing(Device::getStatus).reversed()).collect(Collectors.toList());
        return devices;
    }
}
